package com.zhijian.medical.service.impl;

import cn.hutool.core.date.DateUtil;
import com.zhijian.medical.entity.vo.request.ArticleSearchVo;
import com.zhijian.medical.entity.vo.request.DeviceSearchVo;
import com.zhijian.medical.entity.vo.request.ExperimentProcessSampleSearchVo;
import com.zhijian.medical.entity.vo.request.PersonSearchVo;
import com.zhijian.medical.entity.vo.response.DeviceDataVo;
import com.zhijian.medical.entity.vo.response.ExperimentProcessSampleDataVo;
import com.zhijian.medical.entity.vo.response.PersonDataVo;
import com.zhijian.medical.enums.DeviceStatusEnum;
import com.zhijian.medical.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;

/**
 * @author HCG
 * @version 1.0
 * @date 2022/9/20
 */
@Slf4j
@Service
public class DataBoardServiceImpl implements DataBoardService {

    @Autowired
    private ExperimentProcessSampleService experimentProcessSampleService;

    @Autowired
    private PersonService personService;

    @Autowired
    private ArticleService articleService;

    @Autowired
    private DeviceService deviceService;

    @Override
    public ExperimentProcessSampleDataVo createExperimentProcessSampleDataVo() {
        Date now = new Date();

        //处理样本数量
        Integer allCount = experimentProcessSampleService.count(ExperimentProcessSampleSearchVo.builder().build());
        //昨日处理样本数
        Integer yesterdayCount = experimentProcessSampleService.count(ExperimentProcessSampleSearchVo.builder()
                .createTimeStart(DateUtil.formatDateTime(DateUtil.beginOfDay(DateUtil.yesterday())))
                .createTimeEnd(DateUtil.formatDateTime(DateUtil.endOfDay(DateUtil.yesterday())))
                .build());
        //今日处理样本数
        Integer todayCount = experimentProcessSampleService.count(ExperimentProcessSampleSearchVo.builder()
                .createTimeStart(DateUtil.formatDateTime(DateUtil.beginOfDay(now)))
                .createTimeEnd(DateUtil.formatDateTime(now))
                .build());
        //日环比上升或者下降
        Integer dailyRatioUpOrDown = Integer.compare(todayCount, yesterdayCount);
        //日环比
        BigDecimal dailyRatio;
        if (dailyRatioUpOrDown == 0) {
            dailyRatio = BigDecimal.ZERO;
        } else if (dailyRatioUpOrDown == 1) {
            //上升
            if (yesterdayCount == 0) {
                dailyRatio = new BigDecimal("100");
            } else {
                BigDecimal divide = new BigDecimal(String.valueOf(todayCount - yesterdayCount)).divide(new BigDecimal(String.valueOf(yesterdayCount)), 2, RoundingMode.HALF_UP);
                dailyRatio = new BigDecimal(divide.doubleValue() * 100 + "");
            }
        } else {
            if (yesterdayCount == 0) {
                dailyRatio = new BigDecimal("100");
            } else {
                BigDecimal divide = new BigDecimal(String.valueOf(yesterdayCount - todayCount)).divide(new BigDecimal(String.valueOf(yesterdayCount)), 2, RoundingMode.HALF_UP);
                dailyRatio = new BigDecimal(divide.doubleValue() * 100 + "");
            }
        }
        //上周处理样本数
        Integer lastWeekCount = experimentProcessSampleService.count(ExperimentProcessSampleSearchVo.builder()
                .createTimeStart(DateUtil.formatDateTime(DateUtil.beginOfWeek(DateUtil.lastWeek())))
                .createTimeEnd(DateUtil.formatDateTime(DateUtil.endOfWeek(DateUtil.lastWeek())))
                .build());
        //本周处理样本数
        Integer thisWeekCount = experimentProcessSampleService.count(ExperimentProcessSampleSearchVo.builder()
                .createTimeStart(DateUtil.formatDateTime(DateUtil.beginOfWeek(now)))
                .createTimeEnd(DateUtil.formatDateTime(now))
                .build());
        //周环比上升或者下降
        Integer weekRatioUpOrDown = Integer.compare(thisWeekCount, lastWeekCount);
        //周环比
        BigDecimal weekRatio;
        if (weekRatioUpOrDown == 0) {
            weekRatio = BigDecimal.ZERO;
        } else if (weekRatioUpOrDown == 1) {
            //上升
            if (lastWeekCount == 0) {
                weekRatio = new BigDecimal("100");
            } else {
                BigDecimal divide = new BigDecimal(String.valueOf(thisWeekCount - lastWeekCount)).divide(new BigDecimal(String.valueOf(lastWeekCount)), 2, RoundingMode.HALF_UP);
                weekRatio = new BigDecimal(divide.doubleValue() * 100 + "");
            }
        } else {
            if (lastWeekCount == 0) {
                weekRatio = new BigDecimal("100");
            } else {
                BigDecimal divide = new BigDecimal(String.valueOf(lastWeekCount - thisWeekCount)).divide(new BigDecimal(String.valueOf(lastWeekCount)), 2, RoundingMode.HALF_UP);
                weekRatio = new BigDecimal(divide.doubleValue() * 100 + "");
            }
        }
        //上月处理样本数
        Integer lastMonthCount = experimentProcessSampleService.count(ExperimentProcessSampleSearchVo.builder()
                .createTimeStart(DateUtil.formatDateTime(DateUtil.beginOfMonth(DateUtil.lastMonth())))
                .createTimeEnd(DateUtil.formatDateTime(DateUtil.endOfMonth(DateUtil.lastMonth())))
                .build());
        //本月处理样本数
        Integer thisMonthCount = experimentProcessSampleService.count(ExperimentProcessSampleSearchVo.builder()
                .createTimeStart(DateUtil.formatDateTime(DateUtil.beginOfMonth(now)))
                .createTimeEnd(DateUtil.formatDateTime(now))
                .build());
        //月环比上升或者下降
        Integer monthRatioUpOrDown = Integer.compare(thisMonthCount, lastMonthCount);
        //月环比
        BigDecimal monthRatio;
        if (monthRatioUpOrDown == 0) {
            monthRatio = BigDecimal.ZERO;
        } else if (monthRatioUpOrDown == 1) {
            //上升
            if (lastMonthCount == 0) {
                monthRatio = new BigDecimal("100");
            } else {
                BigDecimal divide = new BigDecimal(String.valueOf(thisMonthCount - lastMonthCount)).divide(new BigDecimal(String.valueOf(lastMonthCount)), 2, RoundingMode.HALF_UP);
                monthRatio = new BigDecimal(divide.doubleValue() * 100 + "");
            }
        } else {
            if (lastMonthCount == 0) {
                monthRatio = new BigDecimal("100");
            } else {
                BigDecimal divide = new BigDecimal(String.valueOf(lastMonthCount - thisMonthCount)).divide(new BigDecimal(String.valueOf(lastMonthCount)), 2, RoundingMode.HALF_UP);
                monthRatio = new BigDecimal(divide.doubleValue() * 100 + "");
            }
        }
        return ExperimentProcessSampleDataVo.builder()
                .allCount(allCount)
                .yesterdayCount(yesterdayCount)
                .thisWeekCount(thisWeekCount)
                .thisMonthCount(thisMonthCount)
                .dailyRatio(dailyRatio)
                .dailyRatioUpOrDown(dailyRatioUpOrDown)
                .weekRatio(weekRatio)
                .weekRatioUpOrDown(weekRatioUpOrDown)
                .monthRatio(monthRatio)
                .monthRatioUpOrDown(monthRatioUpOrDown)
                .build();
    }

    @Override
    public PersonDataVo createPersonDataVo() {
        //人员总数
        Integer allCount = personService.count(PersonSearchVo.builder().build());
        //文章总数
        Integer articleCount = articleService.count(ArticleSearchVo.builder().build());
        //研究成果 todo
        Integer researchFindingsCount = 0;
        return PersonDataVo.builder()
                .allCount(allCount)
                .articleCount(articleCount)
                .researchFindingsCount(researchFindingsCount)
                .build();
    }

    @Override
    public DeviceDataVo createDeviceDataVo() {
        //检修总数
        Integer repairCount = deviceService.count(DeviceSearchVo.builder()
                .status(DeviceStatusEnum.REPAIR.getAlias())
                .build());
        //运行总数
        Integer runningCount = deviceService.count(DeviceSearchVo.builder()
                .status(DeviceStatusEnum.RUNNING.getAlias())
                .build());
        //封存总数
        Integer storeCount = deviceService.count(DeviceSearchVo.builder()
                .status(DeviceStatusEnum.STORE.getAlias())
                .build());
        //待机总数
        Integer awaitingCount = deviceService.count(DeviceSearchVo.builder()
                .status(DeviceStatusEnum.AWAITING.getAlias())
                .build());
        return DeviceDataVo.builder()
                .repairCount(repairCount)
                .runningCount(runningCount)
                .storeCount(storeCount)
                .awaitingCount(awaitingCount)
                .build();
    }

}
